package edu.gzhu.guli.front.service.impl;

import edu.gzhu.guli.core.common.ApplicationResult;
import edu.gzhu.guli.core.entity.Chapter;
import edu.gzhu.guli.core.entity.Course;
import edu.gzhu.guli.core.entity.Subject;
import edu.gzhu.guli.core.entity.Video;
import edu.gzhu.guli.core.repository.ChapterRepository;
import edu.gzhu.guli.core.repository.CourseRepository;
import edu.gzhu.guli.core.repository.SubjectRepository;
import edu.gzhu.guli.core.repository.VideoRepository;
import edu.gzhu.guli.front.dto.*;
import edu.gzhu.guli.front.service.CourseService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CourseServiceImpl implements CourseService {
    /**    被合并代码
     *
     *     @Resource
     *     private CourseRepository courseRepository;
     *
     *     @Resource
     *     private ModelMapper modelMapper;
     */
    @Autowired
    private CourseRepository courseRepository;

    @Autowired
    private ChapterRepository chapterRepository;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private VideoRepository videoRepository;

    @Autowired
    private edu.gzhu.guli.core.video.VideoService videoService;

    @Operation(summary = "获取课程信息")
    @Override
    public ApplicationResult<CourseInfoDto> getCourseDetailsById(Long courseId, CourseInfoDto courseInfoDto) {
        Optional<Course> optionalCourse = courseRepository.findById(courseId);
        if (!optionalCourse.isPresent())
            return ApplicationResult.failure("课程ID为: " + courseId + "课程未找到");
        Course course = optionalCourse.get();
        modelMapper.map(course, courseInfoDto);
        log.info("封装course基本信息:{}", courseInfoDto);
        List<Chapter> chapters = course.getChapters();
        List<ChapterInfoDto> chapterInfoDtoList = chapters
                .stream()
                .map(chapter -> modelMapper.map(chapter, ChapterInfoDto.class))
                .collect(Collectors.toList());
        log.info("封装章节信息: {}", chapterInfoDtoList);
        /**
         *         for (int i = 0; i < chapters.size(); i++) {
         *             List<VideoInfoDto> videoInfoDtos = chapters.get(i).getVideos()
         *                     .stream()
         *                     .map(video -> modelMapper.map(video, VideoInfoDto.class))
         *                     .collect(Collectors.toList());
         *             log.info("封装ID为：" + courseId + "的章节视频信息: {}", videoInfoDtos);
         *             chapterInfoDtoList.get(i).setVideoInfoDtoList(videoInfoDtos);
         *         }
         */
        for (int i = 0; i < chapters.size(); i++) {
            VideoInfoDto videoInfoDto = modelMapper.map(chapters.get(i).getVideo(), VideoInfoDto.class);
            chapterInfoDtoList.get(i).setVideoInfoDto(videoInfoDto);
            log.info("封装ID为：" + courseId + "的章节视频信息: {}", videoInfoDto);
        }
        courseInfoDto.setChapterInfoDtoList(chapterInfoDtoList);
        List<CommentInfoDto> commentInfoDtos = course.getComments()
                .stream()
                .map(comment -> modelMapper.map(comment, CommentInfoDto.class))
                .collect(Collectors.toList());
        log.info("封装用户评论信息：{}", commentInfoDtos);
        courseInfoDto.setCommentInfoDtoList(commentInfoDtos);
        return ApplicationResult.succese(courseInfoDto);
    }

    @Override
    public ApplicationResult<List<CourseListItemDto>> getCourses(String searchContent,String topSubjectId,String subjectId,
                                                                 String listType,int page,int limit) {
        try{
            // 默认排序方式为最热(播放次数最多)
            PageRequest pageRequest = PageRequest.of(page-1, limit, Sort.Direction.DESC,"viewCount");
            // 设置培训方式及分页
            if(listType.equals("最新")){
                pageRequest = PageRequest.of(page-1, limit, Sort.Direction.DESC,"createTime");
            }else if(listType.equals("价格最高")){
                pageRequest = PageRequest.of(page-1, limit, Sort.Direction.DESC,"price");
            }else if(listType.equals("价格最低")){
                pageRequest = PageRequest.of(page-1, limit, Sort.Direction.ASC,"price");
            }

            // 动态SQL进一步拼接检索条件
            Page<Course> all = courseRepository.findAll((Specification<Course>) (root, query, criteriaBuilder) -> {
                Predicate predicate = criteriaBuilder.conjunction();
                if (!searchContent.equals("")) {
                    // 如果搜索条件不为空则拼接条件(模糊查询)
                    predicate.getExpressions().add(criteriaBuilder.like(root.get("title"), "%" + searchContent + "%"));
                }
                if (!topSubjectId.equals("")) {
                    // 如果顶层分类不为空则拼接条件
                    predicate.getExpressions().add(criteriaBuilder.equal(root.get("topSubject").get("id"), Long.valueOf(topSubjectId)));
                }
                if (!subjectId.equals("")) {
                    // 如果次层分类不为空则拼接条件
                    predicate.getExpressions().add(criteriaBuilder.equal(root.get("subject").get("id"), Long.valueOf(subjectId)));
                }
                return predicate;
            }, pageRequest);

            // 映射Dto
            List<CourseListItemDto> result = all
                    .stream()
                    .map(it -> modelMapper.map(it, CourseListItemDto.class))
                    .collect(Collectors.toList());

            return ApplicationResult.succese(result);

        }catch (Exception e){
            e.printStackTrace();
            return ApplicationResult.failure("获取失败");
        }
    }
    @Override
    public ApplicationResult<String> getVideoAuthById(String id) {
        Optional<Video> optionalVideo = videoRepository.findById(Long.parseLong(id));
        if (!optionalVideo.isPresent())
            return ApplicationResult.failure("未获取到id为："+ id + "的视频");
        Video video = optionalVideo.get();
        String sourceId = video.getSourceId();
        String playAuth = videoService.getVideoAuth(sourceId);
        if (playAuth == null) return ApplicationResult.failure("获取播放凭证失败");
        return ApplicationResult.succese(playAuth);
    }
}
